﻿using System;
using Framework.MVC;
using Log.Model;
using Billing.Model;
using Billing.Model.Behavior;
using Billing.IService.Entry;
using Framework.MVVM.Model;
using Common.IService;
using Common.Service;
using Log.IService;
using Log.Service;
using Billing.IService;
using Billing.Service;
using Common.IService.Entry;
using Config.IService;
using Config.Service;
using Config.Model;
using Framework.Extention.Filter;


namespace Billing.Models
{
    [ServiceAttribute(typeof(IConfigService), typeof(ConfigService), "Instance")]
    [ServiceAttribute(typeof(IOrderService), typeof(PayOrderService), "Instance")]
    [ServiceAttribute(typeof(ILogService), typeof(LogService), "Instance")]
    [ServiceAttribute(typeof(ICodeService), typeof(CodeService), "Instance")]
    public class EndPayModel : AsyncModelBase, IWriteLog, IGetOrder, IModifyOrderStatus, IGetConfig<IFilter<string>>
    {
        #region Field

        private const string m_ip_error = "endpay001";
        private const string m_ip_complete = "endpay002";
        private const string m_get_error = "endpay003";
        private const string m_get_complete = "endpay004";
        private const string m_modify_error = "endpay005";
        private const string m_modify_complete = "endpay006";

        private OrderEntry m_entry;

        private const string m_result = "result";

        #endregion Field

        #region Property

        public string Source { get; set; }

        public decimal Amount { get; set; }

        #endregion Property

        #region AsyncModelBase

        protected override void OnInit(Type type)
        {
            OnBeginRequest();
            this.GetConfig<IFilter<string>>(m_ip_error, m_ip_complete);
        }

        #endregion AsyncModelBase

        #region IWriteLog

        public void OnWriteLogComplete(string eventCode)
        {
            OnEndRequest();
        }

        public void OnWriteLogError(string eventCode)
        {
            OnEndRequest();
        }

        #endregion IWriteLog

        #region IGetConfig IP Filter

        public string ConfigName { get; set; }

        public void OnGetConfigComplete(string key, IFilter<string> entry)
        {
            bool validate = entry.Validate(Source);
            if (validate)
            {
                OnBeginRequest();
                this.GetOrder(m_get_error, m_get_complete);
            }
            this.Log(key, new SourceEntry<bool> { source = Source, data = validate });
        }

        public void OnGetConfigError(string key)
        {
            this.Log(key, Source);
        }

        #endregion IGetConfig IP Filter

        #region IGetOrder

        public string OrderCode { get; set; }

        public string OrderSource { get; set; }

        public void OnGetOrderComplete(string key, OrderEntry entry)
        {
            if (entry.status == 1)
            {
                entry.status = (byte)(entry.amount == Amount ? 2 : 3);
                OrderStatus = entry.status;
                OrderVersion = entry.version;
                m_entry = entry;
                OnBeginRequest();
                this.ModifyOrderStatus(m_modify_error,m_modify_complete);
            }
            this.Log(key, new SourceEntry<OrderEntry> { source = Source, data = entry });
        }

        public void OnGetOrderError(string key)
        {
            this.Log(key, new SourceEntry<OrderEntry> { source = Source, data = new OrderEntry { orderCode = OrderCode, sourceCode = OrderSource } });
        }

        #endregion IGetOrder

        #region IModifyOrderStatus

        public byte OrderStatus { get; set; }

        public byte OrderVersion { get; set; }

        public void OnModifyOrderComplete(string key, OrderEntry entry)
        {
            OnComplete(m_result, entry.status);
            this.Log(key, new SourceEntry<OrderEntry> { source = Source, data = m_entry });
        }
        public void OnModifyOrderError(string key)
        {
            this.Log(key, new SourceEntry<OrderEntry> { source = Source, data = m_entry });
        }

        #endregion IModifyOrderStatus
    }
}